package tfmcbs.diagram.providers;

import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;

import tfmcbs.TfmcbsPackage;
import tfmcbs.diagram.edit.parts.Artifact2EditPart;
import tfmcbs.diagram.edit.parts.ArtifactEditPart;
import tfmcbs.diagram.edit.parts.CompositeComponent2EditPart;
import tfmcbs.diagram.edit.parts.CompositeComponent3EditPart;
import tfmcbs.diagram.edit.parts.CompositeComponentEditPart;
import tfmcbs.diagram.edit.parts.ConnectionEditPart;
import tfmcbs.diagram.edit.parts.DependencyEditPart;
import tfmcbs.diagram.edit.parts.EntityExtendsEditPart;
import tfmcbs.diagram.edit.parts.Interface2EditPart;
import tfmcbs.diagram.edit.parts.InterfaceEditPart;
import tfmcbs.diagram.edit.parts.ManifestationEditPart;
import tfmcbs.diagram.edit.parts.ModelEditPart;
import tfmcbs.diagram.edit.parts.PortRealizationEditPart;
import tfmcbs.diagram.edit.parts.PortUsageEditPart;
import tfmcbs.diagram.edit.parts.PrimitiveComponent2EditPart;
import tfmcbs.diagram.edit.parts.PrimitiveComponentEditPart;
import tfmcbs.diagram.edit.parts.PrimitiveRealizationEditPart;
import tfmcbs.diagram.edit.parts.PrimitiveUsageEditPart;
import tfmcbs.diagram.edit.parts.ProvidingPortDelegateEditPart;
import tfmcbs.diagram.edit.parts.ProvidingPortEditPart;
import tfmcbs.diagram.edit.parts.RequiringPortDelegateEditPart;
import tfmcbs.diagram.edit.parts.RequiringPortEditPart;
import tfmcbs.diagram.part.ComponentBasedSystemDiagramEditorPlugin;

/**
 * @generated
 */
public class ComponentBasedSystemElementTypes {

	/**
	 * @generated
	 */
	private ComponentBasedSystemElementTypes() {
	}

	/**
	 * @generated
	 */
	private static Map<IElementType, ENamedElement> elements;

	/**
	 * @generated
	 */
	private static ImageRegistry imageRegistry;

	/**
	 * @generated
	 */
	private static Set<IElementType> KNOWN_ELEMENT_TYPES;

	/**
	 * @generated
	 */
	public static final IElementType Model_1000 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Model_1000"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PrimitiveComponent_2022 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PrimitiveComponent_2022"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType CompositeComponent_2023 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.CompositeComponent_2023"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Interface_2024 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Interface_2024"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Artifact_2025 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Artifact_2025"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PrimitiveComponent_3019 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PrimitiveComponent_3019"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType CompositeComponent_3020 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.CompositeComponent_3020"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Interface_3021 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Interface_3021"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Artifact_3022 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Artifact_3022"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType ProvidingPort_3014 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.ProvidingPort_3014"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType RequiringPort_3015 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.RequiringPort_3015"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Connection_4037 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Connection_4037"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Dependency_4038 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Dependency_4038"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Manifestation_4039 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.Manifestation_4039"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PrimitiveUsage_4050 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PrimitiveUsage_4050"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PortUsage_4041 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PortUsage_4041"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PrimitiveRealization_4042 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PrimitiveRealization_4042"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType PortRealization_4043 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.PortRealization_4043"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType ProvidingPortDelegate_4047 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.ProvidingPortDelegate_4047"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType RequiringPortDelegate_4048 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.RequiringPortDelegate_4048"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType EntityExtends_4046 = getElementType("cz.vutbr.fit.xzemko01.tool-for-modelling-of-component-based-systems.diagram.EntityExtends_4046"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	private static ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry();
		}
		return imageRegistry;
	}

	/**
	 * @generated
	 */
	private static String getImageRegistryKey(ENamedElement element) {
		return element.getName();
	}

	/**
	 * @generated
	 */
	private static ImageDescriptor getProvidedImageDescriptor(
			ENamedElement element) {
		if (element instanceof EStructuralFeature) {
			EStructuralFeature feature = ((EStructuralFeature) element);
			EClass eContainingClass = feature.getEContainingClass();
			EClassifier eType = feature.getEType();
			if (eContainingClass != null && !eContainingClass.isAbstract()) {
				element = eContainingClass;
			} else if (eType instanceof EClass
					&& !((EClass) eType).isAbstract()) {
				element = eType;
			}
		}
		if (element instanceof EClass) {
			EClass eClass = (EClass) element;
			if (!eClass.isAbstract()) {
				return ComponentBasedSystemDiagramEditorPlugin.getInstance()
						.getItemImageDescriptor(
								eClass.getEPackage().getEFactoryInstance()
										.create(eClass));
			}
		}
		// TODO : support structural features
		return null;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(ENamedElement element) {
		String key = getImageRegistryKey(element);
		ImageDescriptor imageDescriptor = getImageRegistry().getDescriptor(key);
		if (imageDescriptor == null) {
			imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
		}
		return imageDescriptor;
	}

	/**
	 * @generated
	 */
	public static Image getImage(ENamedElement element) {
		String key = getImageRegistryKey(element);
		Image image = getImageRegistry().get(key);
		if (image == null) {
			ImageDescriptor imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
			image = getImageRegistry().get(key);
		}
		return image;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImageDescriptor(element);
	}

	/**
	 * @generated
	 */
	public static Image getImage(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImage(element);
	}

	/**
	 * Returns 'type' of the ecore object associated with the hint.
	 * 
	 * @generated
	 */
	public static ENamedElement getElement(IAdaptable hint) {
		Object type = hint.getAdapter(IElementType.class);
		if (elements == null) {
			elements = new IdentityHashMap<IElementType, ENamedElement>();

			elements.put(Model_1000, TfmcbsPackage.eINSTANCE.getModel());

			elements.put(PrimitiveComponent_2022,
					TfmcbsPackage.eINSTANCE.getPrimitiveComponent());

			elements.put(CompositeComponent_2023,
					TfmcbsPackage.eINSTANCE.getCompositeComponent());

			elements.put(Interface_2024, TfmcbsPackage.eINSTANCE.getInterface());

			elements.put(Artifact_2025, TfmcbsPackage.eINSTANCE.getArtifact());

			elements.put(PrimitiveComponent_3019,
					TfmcbsPackage.eINSTANCE.getPrimitiveComponent());

			elements.put(CompositeComponent_3020,
					TfmcbsPackage.eINSTANCE.getCompositeComponent());

			elements.put(Interface_3021, TfmcbsPackage.eINSTANCE.getInterface());

			elements.put(Artifact_3022, TfmcbsPackage.eINSTANCE.getArtifact());

			elements.put(ProvidingPort_3014,
					TfmcbsPackage.eINSTANCE.getProvidingPort());

			elements.put(RequiringPort_3015,
					TfmcbsPackage.eINSTANCE.getRequiringPort());

			elements.put(Connection_4037,
					TfmcbsPackage.eINSTANCE.getConnection());

			elements.put(Dependency_4038,
					TfmcbsPackage.eINSTANCE.getDependency());

			elements.put(Manifestation_4039,
					TfmcbsPackage.eINSTANCE.getManifestation());

			elements.put(PrimitiveUsage_4050,
					TfmcbsPackage.eINSTANCE.getPrimitiveUsage());

			elements.put(PortUsage_4041, TfmcbsPackage.eINSTANCE.getPortUsage());

			elements.put(PrimitiveRealization_4042,
					TfmcbsPackage.eINSTANCE.getPrimitiveRealization());

			elements.put(PortRealization_4043,
					TfmcbsPackage.eINSTANCE.getPortRealization());

			elements.put(ProvidingPortDelegate_4047,
					TfmcbsPackage.eINSTANCE.getProvidingPort_Delegate());

			elements.put(RequiringPortDelegate_4048,
					TfmcbsPackage.eINSTANCE.getRequiringPort_Delegate());

			elements.put(EntityExtends_4046,
					TfmcbsPackage.eINSTANCE.getEntity_Extends());
		}
		return (ENamedElement) elements.get(type);
	}

	/**
	 * @generated
	 */
	private static IElementType getElementType(String id) {
		return ElementTypeRegistry.getInstance().getType(id);
	}

	/**
	 * @generated
	 */
	public static boolean isKnownElementType(IElementType elementType) {
		if (KNOWN_ELEMENT_TYPES == null) {
			KNOWN_ELEMENT_TYPES = new HashSet<IElementType>();
			KNOWN_ELEMENT_TYPES.add(Model_1000);
			KNOWN_ELEMENT_TYPES.add(PrimitiveComponent_2022);
			KNOWN_ELEMENT_TYPES.add(CompositeComponent_2023);
			KNOWN_ELEMENT_TYPES.add(Interface_2024);
			KNOWN_ELEMENT_TYPES.add(Artifact_2025);
			KNOWN_ELEMENT_TYPES.add(PrimitiveComponent_3019);
			KNOWN_ELEMENT_TYPES.add(CompositeComponent_3020);
			KNOWN_ELEMENT_TYPES.add(Interface_3021);
			KNOWN_ELEMENT_TYPES.add(Artifact_3022);
			KNOWN_ELEMENT_TYPES.add(ProvidingPort_3014);
			KNOWN_ELEMENT_TYPES.add(RequiringPort_3015);
			KNOWN_ELEMENT_TYPES.add(Connection_4037);
			KNOWN_ELEMENT_TYPES.add(Dependency_4038);
			KNOWN_ELEMENT_TYPES.add(Manifestation_4039);
			KNOWN_ELEMENT_TYPES.add(PrimitiveUsage_4050);
			KNOWN_ELEMENT_TYPES.add(PortUsage_4041);
			KNOWN_ELEMENT_TYPES.add(PrimitiveRealization_4042);
			KNOWN_ELEMENT_TYPES.add(PortRealization_4043);
			KNOWN_ELEMENT_TYPES.add(ProvidingPortDelegate_4047);
			KNOWN_ELEMENT_TYPES.add(RequiringPortDelegate_4048);
			KNOWN_ELEMENT_TYPES.add(EntityExtends_4046);
		}
		return KNOWN_ELEMENT_TYPES.contains(elementType);
	}

	/**
	 * @generated
	 */
	public static IElementType getElementType(int visualID) {
		switch (visualID) {
		case ModelEditPart.VISUAL_ID:
			return Model_1000;
		case PrimitiveComponentEditPart.VISUAL_ID:
			return PrimitiveComponent_2022;
		case CompositeComponentEditPart.VISUAL_ID:
			return CompositeComponent_2023;
		case InterfaceEditPart.VISUAL_ID:
			return Interface_2024;
		case ArtifactEditPart.VISUAL_ID:
			return Artifact_2025;
		case PrimitiveComponent2EditPart.VISUAL_ID:
			return PrimitiveComponent_3019;
		case CompositeComponent2EditPart.VISUAL_ID:
			return CompositeComponent_3020;
		case Interface2EditPart.VISUAL_ID:
			return Interface_3021;
		case Artifact2EditPart.VISUAL_ID:
			return Artifact_3022;
		case ProvidingPortEditPart.VISUAL_ID:
			return ProvidingPort_3014;
		case RequiringPortEditPart.VISUAL_ID:
			return RequiringPort_3015;
		case ConnectionEditPart.VISUAL_ID:
			return Connection_4037;
		case DependencyEditPart.VISUAL_ID:
			return Dependency_4038;
		case ManifestationEditPart.VISUAL_ID:
			return Manifestation_4039;
		case PrimitiveUsageEditPart.VISUAL_ID:
			return PrimitiveUsage_4050;
		case PortUsageEditPart.VISUAL_ID:
			return PortUsage_4041;
		case PrimitiveRealizationEditPart.VISUAL_ID:
			return PrimitiveRealization_4042;
		case PortRealizationEditPart.VISUAL_ID:
			return PortRealization_4043;
		case ProvidingPortDelegateEditPart.VISUAL_ID:
			return ProvidingPortDelegate_4047;
		case RequiringPortDelegateEditPart.VISUAL_ID:
			return RequiringPortDelegate_4048;
		case EntityExtendsEditPart.VISUAL_ID:
			return EntityExtends_4046;
		}
		return null;
	}

}
